#ifndef CHUNK_H
#define CHUNK_H

#include "DXUT.h"

#include "Block.h"
#include "Cavemap.h"
#include "Helper.h"

#include <algorithm>
#include <vector>

using namespace std;

#define BLOCKCOUNT 4096

extern const float g_LightLevels[];

class Chunk: public IWorld
{
private:
	int	  _x;
	int	  _z;
	int	  _y;

	int	  rx;
	int	  rz;

	IWorld *pRegion;
	Block  *pBlocks;

#ifdef RENDER
	ID3D11Buffer*  pVertexBuffer;
	ID3D11Buffer*  pIndexBuffer;

	WORD		   indexSize[2];
	WORD		   indexOffset[2];
	WORD		   vertexOffset[2];

	UINT		   ibSize;
	UINT		   vbSize;

	bool		    dirty;
#endif
	bool			empty;

private:

protected:
	void deLight(int x, int z, int y, char allowedFacing, vector<INTVECTOR3> * plist, byte flags, bool takeblocklight);
	void enLight(int x, int z, int y, char allowedFacing, char recursivDepth, byte flags, bool takeblocklight);
	void reLight(vector<INTVECTOR3> * plist, byte flags, bool takeblocklight);
public:
	Chunk(IWorld* region, int x, int z, int y);
	~Chunk();

	float getTemperature(int x, int z);
	float getHumidity(int x, int z);
	BYTE  getBiome(int x, int z);

	void generateBlocks();
	void generateBlocks(byte *height, Cavemap * cave);

	BYTE * chunkGetMemory();
	void chunkSetMemory(BYTE * data);

	void calculateLight();
	void calculateLight2();
	void resetLight(byte *height);

#ifdef RENDER
	bool isDirty() {return dirty;};
	void Dirty(bool dirty) {this->dirty = dirty;};
	void setDirty(int x, int z, int y, bool immediatly);

	void generateVB(ID3D11Device* pd3dDevice, ID3D11DeviceContext* context);
	void Release();
	void render(const D3DXFRUSTUM frustum, ID3D11DeviceContext* pImmediateContext, int index);
#endif

	void	update();

	Block   getBlock(int x, int z, int y);
	Block * getpBlock(int x, int z, int y);
	void	setBlock(int x, int z, int y, Block block, byte flags = 0);
	Block	breakBlock(int x, int z, int y);
	byte	updateBlock(int x, int z, int y, byte type, byte * ticks);
	void	delayedUpdateBlock(int x, int z, int y, byte type, byte ticks);
};

#endif